package com.rt.gptnext.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rt.gptnext.common.utils.AuthUtil;
import com.rt.gptnext.data.entity.OpenaiChat;
import com.rt.gptnext.data.entity.OpenaiCompletion;
import com.rt.gptnext.data.mapper.OpenaiChatMapper;
import jakarta.annotation.Resource;
import org.hibernate.service.spi.ServiceException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author gaoyiyang
 */
@Service
public class OpenaiChatService extends ServiceImpl<OpenaiChatMapper, OpenaiChat> {

    @Resource
    private OpenaiCompletionService openaiCompletionService;

    @Transactional(rollbackFor = Throwable.class)
    public void remove(Long id) {
        removeById(id);
        openaiCompletionService.lambdaUpdate()
                .eq(OpenaiCompletion::getChatId, id)
                .remove();
    }

    public OpenaiChat initChat(OpenaiChat openaiChat) {
        var chat = new OpenaiChat();
        chat.setUsername(AuthUtil.getUser());
        chat.setName(openaiChat.getName());
        chat.setTemperature(openaiChat.getTemperature());
        chat.setSystemPrompt(openaiChat.getSystemPrompt());
        save(chat);
        return chat;
    }

    public OpenaiChat initChat(String systemPrompt) {
        var chat = new OpenaiChat();
        chat.setUsername(AuthUtil.getUser());
        chat.setSystemPrompt(systemPrompt);
        save(chat);
        return chat;
    }

    public OpenaiChat reset(Long id) {
        OpenaiChat chat = getById(id);
        if (chat == null) {
            throw new ServiceException("聊天不存在");
        }
        // 使用乐观锁机制循环更新版本号，直至更新成功
        int version = chat.getVersion();
        while (!lambdaUpdate()
                .set(OpenaiChat::getVersion, version + 1)
                .eq(OpenaiChat::getId, chat.getId())
                .eq(OpenaiChat::getVersion, version)
                .update()) {
            version += 1;
        }
        chat = getById(id);
        return chat;
    }

    public List<OpenaiChat> chats() {
        return lambdaQuery()
                .eq(OpenaiChat::getUsername, AuthUtil.getUser())
                .list();
    }

}
